%%% daap.erl - an implementation of the daap protocol
%%%
%%% The MIT License
%%%
%%% Copyright (c) 2008 hellomatty@gmail.com
%%%
%%% Permission is hereby granted, free of charge, to any person obtaining a copy
%%% of this software and associated documentation files (the "Software"), to deal
%%% in the Software without restriction, including without limitation the rights
%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%%% copies of the Software, and to permit persons to whom the Software is
%%% furnished to do so, subject to the following conditions:
%%%
%%% The above copyright notice and this permission notice shall be included in
%%% all copies or substantial portions of the Software.
%%%
%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
%%% THE SOFTWARE.
%%%

-module(daap).
-export([process/2]).

-import(content_codes).
-import(bbcprogrammes).
-import(lists, [flatten/1]). 
-import(util).
-include_lib("defs.hrl").

-define(DB_NAME, "BBC Radio").

process(["server-info"],[]) ->
  {send, {dmap,
    {msrv, [
      {mstt, 200},
      {mpro, {version, 2,0}},
      {apro, {version, 3, 0}},
      {minm, ?DB_NAME},
      %% {mslr, false},
      {msau, false},
      {mstm, 1800},
      {msex, false},
      {msix, false},
      {msbr, false},
      {msqy, false},
      {msup, false},
      {msdc, 1}
    ]}
  }};
process(["content-codes"], []) ->
  {send, {dmap,
    {mccr, lists:flatten([
      {mstt, 200},
        [ {mdcl,
          [ {mcna, content_codes:name(Tag)},
            {mcnm, Tag},
            {mcty, content_codes:type_code(Tag)}
        ]
      } || Tag <- content_codes:all()]
    ])}
  }};
process(["update"],_Params) ->
  {send, {dmap,
    {mupd, [
      {mstt, 200},
      {musr, gen_server:call(bbc_programmes_server,revision)}
    ]}
  }};
process(["login"],[]) ->
  {send, {dmap,
    {mlog, [
      {mstt, 200},
      {mlid, 0}
    ]}
  }};
process(["logout"],_Params) ->
  {send, {dmap, {mstt, 200}}};
process(["databases"],[]) ->
  {Genres, Episodes} = gen_server:call(bbcprogrammes_server, state),
  {send, {dmap,
    {avdb,[
      {mstt, 200},
      {muty, 0},
      {mtco, 1},
      {mrco, 1},
      {mlcl, [
        {mlit, [
          {miid, 1},
          {mper, 1},
          {minm, ?DB_NAME},
          {mimc, length(Episodes)},
          {mctc, 1 + length(Genres)}
        ]}
      ]}
    ]}
  }};
process(["databases", _Id, "items"], _Params) -> 
  {_Genres, Episodes} = gen_server:call(bbcprogrammes_server, state),
  {send, {dmap,
    {adbs, [
      {mstt, 200},
      {muty, 0},
      {mtco, length(Episodes)},
      {mrco, length(Episodes)},
      {mlcl, [episode_to_item(Id, Episode) || {Id, Episode} <- Episodes]}
    ]}
  }};
process(["databases", _Id, "containers"], _Params) ->
  {Genres, Episodes} = gen_server:call(bbcprogrammes_server, state),
  {send, {dmap,
    {aply, [
      {mstt, 200},
      {muty, 0},
      {mtco, 1 + length(Genres)},
      {mrco, 1 + length(Genres)},
      {mlcl, lists:append(
        [
          {mlit, [
            {miid, 1},
            {mper, 1},
            {minm, ?DB_NAME},
            {mimc, length(Episodes)}
          ]}
        ],
        [genre_to_item(Id, Genre) || {Id, Genre} <- Genres]
      )}
    ]}
  }};
process(["databases",_DbId,"containers",ContainerId,"items"], _Params) ->
  Ids = case list_to_integer(ContainerId) of
    1 ->
      {_Genres, Episodes} = gen_server:call(bbcprogrammes_server, state),
      lists:map(fun({Id, _Episode}) -> Id end, Episodes);
    Id ->
      Genre = gen_server:call(bbcprogrammes_server, {genre, Id}),
      Genre#genre.episode_ids
  end,
  {send, {dmap,
    {apso, [
      {mstt, 200},
      {muty, 0},
      {mtco, length(Ids)},
      {mrco, length(Ids)},
      {mlcl, [id_to_playlistitem(Id) || Id <- Ids]}
    ]}
  }};
process(["databases",_DbId,"items", Song], _Params) ->
  EpisodeId = list_to_integer(string:substr(Song, 1, string:str(Song, ".") - 1)),
  gen_server:cast(bbcprogrammes_server, {stream, song, id, EpisodeId, self()}),
  {stream, start}.

episode_to_item(Id, Episode) ->
  {mlit, [
    {mikd, 2},
    {asdk, 0},
    {miid, Id},
    {mper, Id},
    {minm, Episode#episode.title},
    {asal, Episode#episode.brand},
    {asar, Episode#episode.service},
    {asdt, Episode#episode.description},
    {asfm, "mp3"},
    {asul,""},
    {asbr,128},
    {ascp, Episode#episode.service},
    {asda,1219664886},
    {asdm,1219664886},
    {asgn,""},
    {assr,44100},
    {assz,4480671},
    {asst,0},
    {assp,0},
% TODO
%   {astm,279902}, % song time
    {astn,5}, % tracknumber
    {asyr,1999}
  ]}.

genre_to_item(Id, Genre) ->
  {mlit, [
    {miid, Id},
    {mper, Id},
    {minm, Genre#genre.title},
    {mimc, length(Genre#genre.episode_ids)}
  ]}.

id_to_playlistitem(Id) ->
  {mlit, [
    {mikd, 2},
    {miid, Id}
  ]}. 
